/**
 *项目：xmlInterf
 *通联支付网络有限公司
 * 作者：张广海
 * 日期：Jan 2, 2013
 * 功能说明：系统对接xml 测试demo
 */
package com.qqtop10.manager.service.impl;

import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.text.SimpleDateFormat;
import java.util.List;

import org.springframework.stereotype.Service;

import com.aipg.common.AipgReq;
import com.aipg.common.AipgRsp;
import com.aipg.common.InfoReq;
import com.aipg.common.XSUtil;
import com.aipg.rnp.Rnp;
import com.aipg.rnp.RnpaRet;
import com.aipg.rtreq.Trans;
import com.aipg.rtrsp.TransRet;
import com.aipg.singleacctvalid.ValidRet;
import com.aipg.transquery.QTDetail;
import com.aipg.transquery.QTransRsp;
import com.allinpay.XmlTools;
import com.qqtop10.manager.model.tltpay.TranxCon;
import com.qqtop10.manager.service.TranxService;

@Service("tranxService")
public class TranxServiceImpl implements TranxService {

	TranxCon tranxContants = new TranxCon();

	/**
	 * 单个代收代付
	 * 
	 * @param trans
	 * @param tranUrl
	 * @param trxCode
	 * @param busicode
	 * @param isFront
	 */
	@Override
	public String createSingleTranx(Trans trans, String tranUrl, String trxCode, String busicode, boolean isFront) {
		String xml = "";
		AipgReq aipg = new AipgReq();

		InfoReq infoReq = makeReq(trxCode);
		aipg.setINFO(infoReq);

		trans.setMERCHANT_ID(tranxContants.merchantId);
		aipg.addTrx(trans);
		xml = XmlTools.buildXml(aipg, true);
		return dealRet(sendToTlt(xml, isFront, tranUrl));
	}
	//
	// public void singleTranx(String url, String trx_code, String busicode,
	// boolean isTLTFront) throws Exception {
	// String xml = "";
	// AipgReq aipg = new AipgReq();
	// InfoReq info = makeReq(trx_code);
	// aipg.setINFO(info);
	// Trans trans = new Trans();
	// trans.setBUSINESS_CODE(busicode);
	// trans.setMERCHANT_ID(tranxContants.merchantId);
	// trans.setSUBMIT_TIME(df.format(new Date()));
	// trans.setACCOUNT_NAME("张三");
	// trans.setACCOUNT_NO("6225211503906389");
	// trans.setACCOUNT_PROP("0");
	// // trans.setACCOUNT_TYPE("01");
	// trans.setAMOUNT("2000");
	// trans.setBANK_CODE("0308");
	// trans.setCURRENCY("CNY");
	// trans.setCUST_USERID("252523524253xx");
	// trans.setTEL("");
	// /*
	// * trans.setBUSINESS_CODE("09900");
	// * trans.setMERCHANT_ID(tranxContants.merchantId);
	// * trans.setSUBMIT_TIME(df.format(new Date()));
	// * trans.setACCOUNT_NAME("康彤瑛");
	// * trans.setACCOUNT_NO("6226661203664520"); trans.setACCOUNT_PROP("0");
	// * // trans.setACCOUNT_TYPE("01"); trans.setAMOUNT("2");
	// * trans.setBANK_CODE("0303"); trans.setCURRENCY("CNY");
	// * trans.setCUST_USERID("410421197808247033"); trans.setTEL("");
	// *
	// */
	//
	// aipg.addTrx(trans);
	//
	// xml = XmlTools.buildXml(aipg, true);
	//
	// dealRet(sendToTlt(xml, isTLTFront, url));
	//
	// }

	public String signMsg(String xml) throws Exception {
		xml = XmlTools.signMsg(xml, tranxContants.pfxPath, tranxContants.pfxPassword, false);
		return xml;
	}

	public boolean verifyMsg(String msg, String cer, boolean isFront) throws Exception {
		boolean flag = XmlTools.verifySign(msg, cer, false, isFront);
		System.out.println("验签结果[" + flag + "]");
		return flag;
	}

	public String sendXml(String xml, String url, boolean isFront) throws UnsupportedEncodingException, Exception {
		System.out.println("======================发送报文======================：\n" + xml);
		String resp = XmlTools.send(url, xml);
		System.out.println("======================响应内容======================");
		boolean flag = this.verifyMsg(resp, tranxContants.tltcerPath, isFront);
		if (flag) {
			System.out.println("响应内容验证通过");
		} else {
			System.out.println("响应内容验证不通过");
		}
		System.out.println(resp);
		return resp;
	}

	public String sendToTlt(String xml, boolean flag, String url) {
		try {
			if (!flag) {
				xml = this.signMsg(xml);
			} else {
				xml = xml.replaceAll("<SIGNED_MSG></SIGNED_MSG>", "");
			}
			return sendXml(xml, url, flag);
		} catch (Exception e) {
			e.printStackTrace();
			if (e.getCause() instanceof ConnectException || e instanceof ConnectException) {
				System.out.println("请求链接中断，如果是支付请求，请做交易结果查询，以确认该笔交易是否已被通联受理，避免重复交易");
			}
		}
		return "请求链接中断，如果是支付请求，请做交易结果查询，以确认该笔交易是否已被通联受理，避免重复交易";
	}

	private InfoReq makeReq(String trxcod) {

		InfoReq info = new InfoReq();
		info.setTRX_CODE(trxcod);
		info.setREQ_SN(tranxContants.merchantId + "-" + String.valueOf(System.currentTimeMillis()));
		info.setUSER_NAME(tranxContants.userName);
		info.setUSER_PASS(tranxContants.password);
		info.setLEVEL("5");
		info.setDATA_TYPE("2");
		info.setVERSION("03");
		if ("300000".equals(trxcod) || "300001".equals(trxcod) || "300003".equals(trxcod) || "REFUND".equals(trxcod)) {
			info.setMERCHANT_ID(tranxContants.merchantId);
		}
		return info;
	}

	/**
	 * 处理响应的逻辑
	 * 
	 * @param retXml
	 *            通联付响应的xml报文
	 */
	public String dealRet(String retXml) {
		String msg = null;
		String trxcode = null;
		AipgRsp aipgrsp = null;
		// 或者交易码
		if (retXml.indexOf("<TRX_CODE>") != -1) {
			int end = retXml.indexOf("</TRX_CODE>");
			int begin = end - 6;
			if (begin >= 0)
				trxcode = retXml.substring(begin, end);
		}
		aipgrsp = XSUtil.parseRsp(retXml);

		switch (trxcode) {
		// 实名付申请
		case "211006":
		case "211006R":
		case "211006C":
			msg = realNamePay(aipgrsp);
			break;
		case "211006Q":
			msg = rnp(aipgrsp);
			break;
		// 交易退款返回处理逻辑
		case "REFUND":
			msg = refund(aipgrsp);
			break;
		// 批量代收付返回处理逻辑
		case "100001":
		case "100002":
		case "211000":
			msg = batchPayment(aipgrsp);
			break;
		// 交易查询处理逻辑
		case "200004":
		case "200005":
			msg = qtransRsp(aipgrsp);
			break;
		// 实时交易结果返回处理逻辑(包括单笔实时代收，单笔实时代付，单笔实时身份验证)
		case "100011":
		case "100014":
		case "100400":
			msg = transRet(aipgrsp);
			break;
		// (单笔实时身份验证结果返回处理逻辑)
		case "211003":
		case "220001":
			msg = validRet(aipgrsp);
			break;
		default:
			msg = aipgrsp.getINFO().getERR_MSG();
			break;
		}
		return msg;
	}

	// if ("211006".equals(trxcode) || "211006R".equals(trxcode) ||
	// "211006C".equals(trxcode)) {
	public String realNamePay(AipgRsp aipgrsp) {
		String msg = null;
		if ("0000".equals(aipgrsp.getINFO().getRET_CODE())) {
			System.out.println("提交成功");
			RnpaRet ret = (RnpaRet) aipgrsp.findObj(RnpaRet.class);
			System.out.println("交易结果：" + ret.getRET_CODE() + ":" + ret.getERR_MSG());
			msg = ret.getERR_MSG();
		} else {
			System.out.println("响应码" + aipgrsp.getINFO().getRET_CODE() + "原因：" + aipgrsp.getINFO().getERR_MSG());
			msg = aipgrsp.getINFO().getERR_MSG();
		}
		return msg;
	}

	// if ("211006Q".equals(trxcode)) {
	public String rnp(AipgRsp aipgRsp) {
		String msg = null;
		if ("0000".equals(aipgRsp.getINFO().getRET_CODE())) {
			System.out.println("提交成功");
			Rnp rnpQ = (Rnp) aipgRsp.getTrxData().get(0);
			System.out.println("查询结果：" + rnpQ.getRET_CODE() + ":" + rnpQ.getERR_MSG());
			msg = rnpQ.getERR_MSG();
		} else {
			System.out.println("响应码" + aipgRsp.getINFO().getRET_CODE() + "原因：" + aipgRsp.getINFO().getERR_MSG());
			msg = aipgRsp.getINFO().getERR_MSG();
		}
		return msg;
	}

	// if ("REFUND".equals(trxcode)) {
	public String refund(AipgRsp aipgrsp) {
		String msg = "退款成功";
		if ("0000".equals(aipgrsp.getINFO().getRET_CODE())) {
			System.out.println("退款成功");
		} else {
			System.out.println("退款失败，失败原因：" + aipgrsp.getINFO().getERR_MSG());
			msg = aipgrsp.getINFO().getERR_MSG();
		}
		return msg;
	}

	// if ("100001".equals(trxcode) || "100002".equals(trxcode) ||
	// "211000".equals(trxcode)) {
	public String batchPayment(AipgRsp aipgrsp) {
		String msg = null;
		if ("0000".equals(aipgrsp.getINFO().getRET_CODE())) {
			System.out.println("受理成功，请在20分钟后进行10/每次的轮询");
			msg = "受理成功";
		} else {
			System.out.println("受理失败，失败原因：" + aipgrsp.getINFO().getERR_MSG());
			msg = "受理失败，失败原因：" + aipgrsp.getINFO().getERR_MSG();
		}
		return msg;
	}

	// if ("200004".equals(trxcode) || "200005".equals(trxcode)) {
	public String qtransRsp(AipgRsp aipgrsp) {
		String msg = null;
		if ("0000".equals(aipgrsp.getINFO().getRET_CODE())) {
			StringBuffer sb = new StringBuffer();
			QTransRsp qrsq = (QTransRsp) aipgrsp.getTrxData().get(0);
			sb.append("查询成功，具体结果明细如下:");
			List<QTDetail> details = qrsq.getDetails();
			for (QTDetail lobj : details) {
				sb.append("原支付交易批次号:" + lobj.getBATCHID() + "  ");
				sb.append("记录序号:" + lobj.getSN() + "  ");
				sb.append("账号:" + lobj.getACCOUNT_NO() + "  ");
				sb.append("户名:" + lobj.getACCOUNT_NAME() + "  ");
				sb.append("金额:" + lobj.getAMOUNT() + "  ");
				sb.append("返回结果:" + lobj.getRET_CODE() + "  ");

				if ("0000".equals(lobj.getRET_CODE())) {
					sb.append("返回说明:交易成功  ");
					sb.append("更新交易库状态（原交易的状态）");
				} else {
					sb.append("返回说明:" + lobj.getERR_MSG() + "  ");
					sb.append("更新交易库状态（原交易的状态）");
				}

			}
			msg = sb.toString();
		} else if ("2000".equals(aipgrsp.getINFO().getRET_CODE()) || "2001".equals(aipgrsp.getINFO().getRET_CODE())
				|| "2003".equals(aipgrsp.getINFO().getRET_CODE()) || "2005".equals(aipgrsp.getINFO().getRET_CODE())
				|| "2007".equals(aipgrsp.getINFO().getRET_CODE()) || "2008".equals(aipgrsp.getINFO().getRET_CODE())) {
			System.out.print("返回说明:" + aipgrsp.getINFO().getRET_CODE() + "  ");
			System.out.println("返回说明：" + aipgrsp.getINFO().getERR_MSG());
			System.out.println("该状态时，说明整个批次的交易都在处理中");

			msg = aipgrsp.getINFO().getERR_MSG();
		} else if ("2004".equals(aipgrsp.getINFO().getRET_CODE())) {
			System.out.println("整批交易未受理通过（最终失败）");
			msg = "整批交易未受理通过";
		} else if ("1002".equals(aipgrsp.getINFO().getRET_CODE())) {
			System.out.println("查询无结果集（表示通联端根据商户请求上送的条件查不到对应的结果集）");
			msg = "查询无结果集";
		} else {
			System.out.println("查询请求失败，请重新发起查询");
			msg = "查询请求失败，请重新发起查询";
		}
		return msg;
	}

	// if ("100011".equals(trxcode) || "100014".equals(trxcode) ||
	// "100400".equals(trxcode)) {
	public String transRet(AipgRsp aipgrsp) {
		String msg = null;
		if ("0000".equals(aipgrsp.getINFO().getRET_CODE())) {
			System.out.println("提交成功");
			TransRet ret = (TransRet) aipgrsp.getTrxData().get(0);
			System.out.println("交易结果：" + ret.getRET_CODE() + ":" + ret.getERR_MSG());
			if ("0000".equals(ret.getRET_CODE())) {
				System.out.println("交易成功（最终结果）");
				msg = "[success]交易成功";
			} else {
				System.out.println("交易失败（最终结果）");
				System.out.println("交易失败原因：" + ret.getERR_MSG());
				msg = "[error]交易失败：" + ret.getERR_MSG();
			}
		} else if ("2000".equals(aipgrsp.getINFO().getRET_CODE()) || "2001".equals(aipgrsp.getINFO().getRET_CODE())
				|| "2003".equals(aipgrsp.getINFO().getRET_CODE()) || "2005".equals(aipgrsp.getINFO().getRET_CODE())
				|| "2007".equals(aipgrsp.getINFO().getRET_CODE()) || "2008".equals(aipgrsp.getINFO().getRET_CODE())) {
			System.out.println("交易处理中或者不确定状态，需要在稍后5分钟后进行交易结果查询（轮询）");
			msg = "[process]交易处理中";
		} else if (aipgrsp.getINFO().getRET_CODE().startsWith("1")) {
			String errormsg = aipgrsp.getINFO().getERR_MSG() == null ? "连接异常，请重试" : aipgrsp.getINFO().getERR_MSG();
			System.out.println("交易请求失败，原因：" + errormsg);
			msg = "[request_error]交易请求失败，原因：" + errormsg;
		} else {
			TransRet ret = (TransRet) aipgrsp.getTrxData().get(0);
			System.out.println("交易失败(最终结果)，失败原因：" + ret.getERR_MSG());
			msg = "[error]交易失败，失败原因：" + ret.getERR_MSG();
		}

		return msg;
	}

	// if ("211003".equals(trxcode) || "220001".equals(trxcode)) {
	public String validRet(AipgRsp aipgrsp) {
		String msg = null;
		if ("0000".equals(aipgrsp.getINFO().getRET_CODE())) {
			System.out.println("提交成功");
			ValidRet ret = (ValidRet) aipgrsp.getTrxData().get(0);
			System.out.println("交易结果：" + ret.getRET_CODE() + ":" + ret.getERR_MSG());
			msg = "交易结果：" + ret.getERR_MSG();
		} else if ("2000".equals(aipgrsp.getINFO().getRET_CODE()) || "2001".equals(aipgrsp.getINFO().getRET_CODE())
				|| "2003".equals(aipgrsp.getINFO().getRET_CODE()) || "2005".equals(aipgrsp.getINFO().getRET_CODE())
				|| "2007".equals(aipgrsp.getINFO().getRET_CODE()) || "2008".equals(aipgrsp.getINFO().getRET_CODE())) {
			System.out.println("验证处理中或者不确定状态，需要在稍后5分钟后进行验证结果查询（轮询）");
			msg = "验证处理中";
		} else if (aipgrsp.getINFO().getRET_CODE().startsWith("1")) {
			String errormsg = aipgrsp.getINFO().getERR_MSG() == null ? "连接异常，请重试" : aipgrsp.getINFO().getERR_MSG();
			System.out.println("验证请求失败，原因：" + errormsg);
			msg = "验证请求失败，原因：" + errormsg;
		} else {
			TransRet ret = (TransRet) aipgrsp.getTrxData().get(0);
			System.out.println("验证失败(最终结果)，失败原因：" + ret.getERR_MSG());
			msg = "验证失败，失败原因：" + ret.getERR_MSG();
		}
		return msg;
	}

}
